<!DOCTYPE html>

<html lang="en">
  <head>
    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>事件管理器（Events Manager） &mdash; Phalcon 2.0.0 文档</title>
    <meta name="keywords" content="php, phalcon, phalcon php, php framework, faster php framework"><link rel="stylesheet" type="text/css" href="../_static/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="http://static.phalconphp.com/css/phalcon.min.css" />
    <link href='https://fonts.googleapis.com/css?family=Open+Sans:700,400' rel='stylesheet' type='text/css'>
    <link href="http://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css" />
    <!--
    EUROPE <link href='https://fonts.googleapis.com/css?family=Open+Sans:700,400&subset=latin-ext' rel='stylesheet' type='text/css'>
    GREEK <link href='https://fonts.googleapis.com/css?family=Open+Sans:700,400&subset=greek-ext' rel='stylesheet' type='text/css'>
    RUSSIA <link href='https://fonts.googleapis.com/css?family=Open+Sans:700,400&subset=cyrillic-ext,latin' rel='stylesheet' type='text/css'>
    -->

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
      <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../_static/docs.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '2.0.0',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>

    <script src="../_static/jquery.min.js"></script>
    <script type="text/javascript" src="../_static/docs.js"></script>
    <link rel="shortcut icon" href="../_static/favicon.ico"/>
    <link rel="top" title="Phalcon 2.0.0 文档" href="../index.html" />
    <link rel="next" title="HTTP 请求环境（Request Environment）" href="request.html" />
    <link rel="prev" title="使用命名空间（Working with Namespaces）" href="namespaces.html" /> 
  </head>
  <body>

<header class="page-header">
    <nav class="navbar" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#main-menu-container">
                    <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
                </button>
                <a class="navbar-brand phalcon-logo" href="/"><span itemprop="name" class="sr-only">Phalcon PHP</span></a>
            </div>

            <div class="collapse navbar-collapse navbar-right" id="main-menu-container">
                <ul class="nav navbar-nav main-menu">
                  <li class="first"><a href="http://phalconphp.com/en/download" class="header-nav-link">Download</a></li>
                  <li><a href="http://docs.phalconphp.com/en/latest/index.html" class="header-nav-link" target="_blank">Documentation</a></li>
                  <li><a href="http://forum.phalconphp.com/" class="header-nav-link" target="_blank">Forum</a></li>
                  <li><a href="http://blog.phalconphp.com/" class="header-nav-link" target="_blank">Blog</a></li>
                  <li><a href="http://phalconphp.com/en/about">About</a></li>
                </ul>
            </div>
        </div>
    </nav>
  </header>

<div class="heading">
    <div class="container">
        <div class="row">
            <h2>Documentation</h2>
        </div>
    </div>
</div>
    <!--<div class="header-line">
      <div class="size-wrap">
        <div class="header-line-title title-white">Documentation</div>
      </div>
    </div>-->
    <div class="related">
      <ul>
        <li class="right" >
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="request.html" title="HTTP 请求环境（Request Environment）"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="namespaces.html" title="使用命名空间（Working with Namespaces）"
             accesskey="P">上一页</a> |</li>
        <li><a href="http://phalconphp.com">Home</a> &raquo;</li>
        <li><a href="../index.html">Phalcon 2.0.0 文档</a> &raquo;</li> 
      </ul>
    </div>  

      <table width="100%" align="center" cellpadding="0" cellspacing="0">
        <tr>
      <td class="primary-box" width="25%" valign="top">
            <div>
            <div id="searchbox" style="">
                <!--<form class="search" action="http://readthedocs.org/search/project/" method="get">
                  <input type="search" name="q" size="25" placeholder="Search">
                  <input type="submit" value="Go">
                  <input type="hidden" name="selected_facets" value="project:">
                </form>-->
                <div style="width:200px;padding:10px">
                  <gcse:searchbox-only></gcse:searchbox-only>
                </div>
            </div>
            </div>
            <div style="padding:5px;padding-left:10px">
              <div id="carbonads-container">
                <div class="carbonad"><div id="azcarbon"></div>
                <script type="text/javascript">var z = document.createElement("script"); z.type = "text/javascript"; z.async = true; z.src = "http://engine.carbonads.com/z/56496/azcarbon_2_1_0_VERT"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(z, s);</script>
                </div></div>
            </div>
            <h3><a href="../index.html">內容目录</a></h3>
            <ul>
<li><a class="reference internal" href="#">事件管理器（Events Manager）</a><ul>
<li><a class="reference internal" href="#usage-example">使用示例（Usage Example）</a></li>
<li><a class="reference internal" href="#creating-components-that-trigger-events">创建组件触发事件（Creating components that trigger Events）</a></li>
<li><a class="reference internal" href="#event-propagation-cancellation">事件传播与取消（Event Propagation/Cancellation）</a></li>
<li><a class="reference internal" href="#listener-priorities">侦听器优先级（Listener Priorities）</a></li>
<li><a class="reference internal" href="#collecting-responses">收集响应（Collecting Responses）</a></li>
<li><a class="reference internal" href="#implementing-your-own-eventsmanager">自定义事件管理器（Implementing your own EventsManager）</a></li>
</ul>
</li>
</ul>

            <h4>上一个主题</h4>
            <p class="topless"><a href="namespaces.html" title="上一章">&lt; 使用命名空间（Working with Namespaces）</a></p>
            <h4>下一个主题</h4>
            <p class="topless"><a href="request.html" title="下一章">HTTP 请求环境（Request Environment） &gt;</a></p>
            <h3>本页</h3>
            <ul class="this-page-menu">
              <li><a href="../_sources/reference/events.txt" rel="nofollow">显示源代码</a></li>
            </ul>
        </td>
          <td class="second-box" valign="top">
            <div class="document">
                <div class="documentwrapper">
                  <div class="bodywrapper">
                    <div class="body" >
                      
  <div class="section" id="events-manager">
<h1>事件管理器（Events Manager）<a class="headerlink" href="#events-manager" title="永久链接至标题">¶</a></h1>
<p>此组件的目的是为了通过创建“钩子”拦截框架中大部分的组件操作。
这些钩子允许开发者获得状态信息，操纵数据或者改变某个组件进程中的执行流向。</p>
<div class="section" id="usage-example">
<h2>使用示例（Usage Example）<a class="headerlink" href="#usage-example" title="永久链接至标题">¶</a></h2>
<p>以下面示例中，我们使用EventsManager来侦听在 <a class="reference internal" href="../api/Phalcon_Db.html"><em>Phalcon\Db</em></a> 管理下的MySQL连接中产生的事件。
首先，我们需要一个侦听者对象来完成这部分的工作。我们创建了一个类，这个类有我们需要侦听事件所对应的方法：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">class</span> <span class="nc">MyDbListener</span>
<span class="p">{</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">afterConnect</span><span class="p">()</span>
    <span class="p">{</span>

    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeQuery</span><span class="p">()</span>
    <span class="p">{</span>

    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">afterQuery</span><span class="p">()</span>
    <span class="p">{</span>

    <span class="p">}</span>

<span class="p">}</span>
</pre></div>
</div>
<p>这个新的类可能有点啰嗦，但我们需要这样做。
事件管理器在组件和我们的侦听类之间充当着接口角色，并提供了基于在我们侦听类中所定义方法的钩子：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Events\Manager</span> <span class="k">as</span> <span class="nx">EventsManager</span><span class="p">,</span>
    <span class="nx">Phalcon\Db\Adapter\Pdo\Mysql</span> <span class="k">as</span> <span class="nx">DbAdapter</span><span class="p">;</span>

<span class="nv">$eventsManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventsManager</span><span class="p">();</span>

<span class="c1">//创建一个数据库侦听</span>
<span class="nv">$dbListener</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyDbListener</span><span class="p">();</span>

<span class="c1">//侦听全部数据库事件</span>
<span class="nv">$eventsManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;db&#39;</span><span class="p">,</span> <span class="nv">$dbListener</span><span class="p">);</span>

<span class="nv">$connection</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">DbAdapter</span><span class="p">(</span><span class="k">array</span><span class="p">(</span>
    <span class="s2">&quot;host&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;localhost&quot;</span><span class="p">,</span>
    <span class="s2">&quot;username&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;root&quot;</span><span class="p">,</span>
    <span class="s2">&quot;password&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;secret&quot;</span><span class="p">,</span>
    <span class="s2">&quot;dbname&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;invo&quot;</span>
<span class="p">));</span>

<span class="c1">//将$eventsManager赋值给数据库甜适配器</span>
<span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">setEventsManager</span><span class="p">(</span><span class="nv">$eventsManager</span><span class="p">);</span>

<span class="c1">//发送一个SQL命令到数据库服务器</span>
<span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">query</span><span class="p">(</span><span class="s2">&quot;SELECT * FROM products p WHERE p.status = 1&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>为了纪录我们应用中全部执行的SQL语句，我们需要使用“afterQuery”事件。
第一个传递给事件侦听者的参数包含了关于正在运行事件的上下文信息，第二个则是连接本身。</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Logger\Adapter\File</span> <span class="k">as</span> <span class="nx">Logger</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">MyDbListener</span>
<span class="p">{</span>

    <span class="k">protected</span> <span class="nv">$_logger</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_logger</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Logger</span><span class="p">(</span><span class="s2">&quot;../apps/logs/db.log&quot;</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">afterQuery</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$connection</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_logger</span><span class="o">-&gt;</span><span class="na">log</span><span class="p">(</span><span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">getSQLStatement</span><span class="p">(),</span> <span class="nx">\Phalcon\Logger</span><span class="o">::</span><span class="na">INFO</span><span class="p">);</span>
    <span class="p">}</span>

<span class="p">}</span>
</pre></div>
</div>
<p>作为些示例的一部分，我们同样实现了 Phalcon\Db\Profiler 来检测SQL语句是否超出了期望的执行时间：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Db\Profiler</span><span class="p">,</span>
    <span class="nx">Phalcon\Logger</span><span class="p">,</span>
    <span class="nx">Phalcon\Logger\Adapter\File</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">MyDbListener</span>
<span class="p">{</span>

    <span class="k">protected</span> <span class="nv">$_profiler</span><span class="p">;</span>

    <span class="k">protected</span> <span class="nv">$_logger</span><span class="p">;</span>

    <span class="sd">/**</span>
<span class="sd">     *创建分析器并开始纪录</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_profiler</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Profiler</span><span class="p">();</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_logger</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Logger</span><span class="p">(</span><span class="s2">&quot;../apps/logs/db.log&quot;</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * 如果事件触发器是&#39;beforeQuery&#39;，此函数将会被执行</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeQuery</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$connection</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_profiler</span><span class="o">-&gt;</span><span class="na">startProfile</span><span class="p">(</span><span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">getSQLStatement</span><span class="p">());</span>
    <span class="p">}</span>

    <span class="sd">/**</span>
<span class="sd">     * 如果事件触发器是&#39;afterQuery&#39;，此函数将会被执行</span>
<span class="sd">     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="nf">afterQuery</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$connection</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_logger</span><span class="o">-&gt;</span><span class="na">log</span><span class="p">(</span><span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">getSQLStatement</span><span class="p">(),</span> <span class="nx">Logger</span><span class="o">::</span><span class="na">INFO</span><span class="p">);</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_profiler</span><span class="o">-&gt;</span><span class="na">stopProfile</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getProfiler</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_profiler</span><span class="p">;</span>
    <span class="p">}</span>

<span class="p">}</span>
</pre></div>
</div>
<p>可以从侦听者中获取结果分析数据：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">//发送一个SQL命令到数据库服务器</span>
<span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">(</span><span class="s2">&quot;SELECT * FROM products p WHERE p.status = 1&quot;</span><span class="p">);</span>

<span class="k">foreach</span> <span class="p">(</span><span class="nv">$dbListener</span><span class="o">-&gt;</span><span class="na">getProfiler</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getProfiles</span><span class="p">()</span> <span class="k">as</span> <span class="nv">$profile</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">echo</span> <span class="s2">&quot;SQL语句: &quot;</span><span class="p">,</span> <span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">getSQLStatement</span><span class="p">(),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="k">echo</span> <span class="s2">&quot;开始时间: &quot;</span><span class="p">,</span> <span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">getInitialTime</span><span class="p">(),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="k">echo</span> <span class="s2">&quot;结束时间: &quot;</span><span class="p">,</span> <span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">getFinalTime</span><span class="p">(),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="k">echo</span> <span class="s2">&quot;总共执行的时间: &quot;</span><span class="p">,</span> <span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">getTotalElapsedSeconds</span><span class="p">(),</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>类似地，我们可以注册一个匿名函数来执行这些任务，而不是再分离出一个侦听类（如上面看到的）：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">//侦听全部数据加事件</span>
<span class="nv">$eventManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;db&#39;</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$connection</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getType</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;afterQuery&#39;</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">echo</span> <span class="nv">$connection</span><span class="o">-&gt;</span><span class="na">getSQLStatement</span><span class="p">();</span>
    <span class="p">}</span>
<span class="p">});</span>
</pre></div>
</div>
</div>
<div class="section" id="creating-components-that-trigger-events">
<h2>创建组件触发事件（Creating components that trigger Events）<a class="headerlink" href="#creating-components-that-trigger-events" title="永久链接至标题">¶</a></h2>
<p>你可以在你的应用中为事件管理器的触发事件创建组件。这样的结果是，可以有很多存在的侦听者为这些产生的事件作出响应。
在以下的示例中，我们将会创建一个叫做“MyComponent”组件。这是个意识事件管理器组件；
当它的方法“someTask”被执行时它将触发事件管理器中全部侦听者的两个事件：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Events\EventsAwareInterface</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">MyComponent</span> <span class="k">implements</span> <span class="nx">EventsAwareInterface</span>
<span class="p">{</span>

    <span class="k">protected</span> <span class="nv">$_eventsManager</span><span class="p">;</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">setEventsManager</span><span class="p">(</span><span class="nv">$eventsManager</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_eventsManager</span> <span class="o">=</span> <span class="nv">$eventsManager</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">getEventsManager</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_eventsManager</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">someTask</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_eventsManager</span><span class="o">-&gt;</span><span class="na">fire</span><span class="p">(</span><span class="s2">&quot;my-component:beforeSomeTask&quot;</span><span class="p">,</span> <span class="nv">$this</span><span class="p">);</span>

        <span class="c1">// 做一些你想做的事情</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_eventsManager</span><span class="o">-&gt;</span><span class="na">fire</span><span class="p">(</span><span class="s2">&quot;my-component:afterSomeTask&quot;</span><span class="p">,</span> <span class="nv">$this</span><span class="p">);</span>
    <span class="p">}</span>

<span class="p">}</span>
</pre></div>
</div>
<p>注意到这个组件产生的事件都以“my-component”为前缀。这是一个唯一的关键词，可以帮助我们区分各个组件产生的事件。
你甚至可以在组件的外面生成相同名字的事件。现在让我们来为这个组件创建一个侦听者：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">class</span> <span class="nc">SomeListener</span>
<span class="p">{</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">beforeSomeTask</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$myComponent</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">&quot;这里, beforeSomeTask</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="k">function</span> <span class="nf">afterSomeTask</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$myComponent</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">echo</span> <span class="s2">&quot;这里, afterSomeTask</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
    <span class="p">}</span>

<span class="p">}</span>
</pre></div>
</div>
<p>侦听者可以是简单的一个实现了全部组件触发事件的类。现在让我们把全部的东西整合起来：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">//创建一个事件管理器</span>
<span class="nv">$eventsManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Phalcon\Events\Manager</span><span class="p">();</span>

<span class="c1">//创建MyComponent实例</span>
<span class="nv">$myComponent</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyComponent</span><span class="p">();</span>

<span class="c1">//将事件管理器绑定到创建MyComponent实例实例</span>
<span class="nv">$myComponent</span><span class="o">-&gt;</span><span class="na">setEventsManager</span><span class="p">(</span><span class="nv">$eventsManager</span><span class="p">);</span>

<span class="c1">//为事件管理器附上侦听者</span>
<span class="nv">$eventsManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;my-component&#39;</span><span class="p">,</span> <span class="k">new</span> <span class="nx">SomeListener</span><span class="p">());</span>

<span class="c1">//执行组件的方法</span>
<span class="nv">$myComponent</span><span class="o">-&gt;</span><span class="na">someTask</span><span class="p">();</span>
</pre></div>
</div>
<p>当“someTask”被执行时，在侦听者里面的两个方法将会被执行，并产生以下输出：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="x">这里, beforeSomeTask</span>
<span class="x">这里, afterSomeTask</span>
</pre></div>
</div>
<p>当触发一个事件时也可以使用“fire”中的第三个参数来传递额外的数据：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$eventsManager</span><span class="o">-&gt;</span><span class="na">fire</span><span class="p">(</span><span class="s2">&quot;my-component:afterSomeTask&quot;</span><span class="p">,</span> <span class="nv">$this</span><span class="p">,</span> <span class="nv">$extraData</span><span class="p">);</span>
</pre></div>
</div>
<p>在一个侦听者里，第三个参数可用于接收此参数：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">//从第三个参数接收数据</span>
<span class="nv">$eventManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;my-component&#39;</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$component</span><span class="p">,</span> <span class="nv">$data</span><span class="p">)</span> <span class="p">{</span>
    <span class="nb">print_r</span><span class="p">(</span><span class="nv">$data</span><span class="p">);</span>
<span class="p">});</span>

<span class="c1">//从事件上下文中接收数据</span>
<span class="nv">$eventManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;my-component&#39;</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$component</span><span class="p">)</span> <span class="p">{</span>
    <span class="nb">print_r</span><span class="p">(</span><span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getData</span><span class="p">());</span>
<span class="p">});</span>
</pre></div>
</div>
<p>如果一个侦听者仅是对某个特定类型的事件感兴趣，你要吧直接附上一个侦听者：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="c1">//这个处理器只会在“beforeSomeTask”事件触发时才被执行</span>
<span class="nv">$eventManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;my-component:beforeSomeTask&#39;</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$component</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">//...</span>
<span class="p">});</span>
</pre></div>
</div>
</div>
<div class="section" id="event-propagation-cancellation">
<h2>事件传播与取消（Event Propagation/Cancellation）<a class="headerlink" href="#event-propagation-cancellation" title="永久链接至标题">¶</a></h2>
<p>可能会有多个侦听者添加到同一个事件管理器，这意味着对于相同的事件会通知多个侦听者。
这些侦听者会以它们在事件管理器注册的顺序来通知。有些事件是可以被取消的，暗示着这些事件可以被终止以防其他侦听都再收到事件的通知：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$eventsManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;db&#39;</span><span class="p">,</span> <span class="k">function</span><span class="p">(</span><span class="nv">$event</span><span class="p">,</span> <span class="nv">$connection</span><span class="p">){</span>

    <span class="c1">//如果可以取消，我们就终止此事件</span>
    <span class="k">if</span> <span class="p">(</span><span class="nv">$event</span><span class="o">-&gt;</span><span class="na">isCancelable</span><span class="p">())</span> <span class="p">{</span>
        <span class="c1">//终止事件，这样的话其他侦听都就不会再收到此通知</span>
        <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">stop</span><span class="p">();</span>
    <span class="p">}</span>

    <span class="c1">//...</span>

<span class="p">});</span>
</pre></div>
</div>
<p>默认情况下全部的事件都是可以取消的，甚至框架提供的事件也是可以取消的。
你可以通过在fire中的第四个参数中传递false来指明这是一个不可取消的事件：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$eventsManager</span><span class="o">-&gt;</span><span class="na">fire</span><span class="p">(</span><span class="s2">&quot;my-component:afterSomeTask&quot;</span><span class="p">,</span> <span class="nv">$this</span><span class="p">,</span> <span class="nv">$extraData</span><span class="p">,</span> <span class="k">false</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="listener-priorities">
<h2>侦听器优先级（Listener Priorities）<a class="headerlink" href="#listener-priorities" title="永久链接至标题">¶</a></h2>
<p>当附上侦听者时，你可以设置一个优先级。使用此特性，你可以指定这些侦听者被调用的固定顺序：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="nv">$evManager</span><span class="o">-&gt;</span><span class="na">enablePriorities</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>

<span class="nv">$evManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;db&#39;</span><span class="p">,</span> <span class="k">new</span> <span class="nx">DbListener</span><span class="p">(),</span> <span class="mi">150</span><span class="p">);</span> <span class="c1">//高优先级</span>
<span class="nv">$evManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;db&#39;</span><span class="p">,</span> <span class="k">new</span> <span class="nx">DbListener</span><span class="p">(),</span> <span class="mi">100</span><span class="p">);</span> <span class="c1">//正常优先级</span>
<span class="nv">$evManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;db&#39;</span><span class="p">,</span> <span class="k">new</span> <span class="nx">DbListener</span><span class="p">(),</span> <span class="mi">50</span><span class="p">);</span> <span class="c1">//低优先级</span>
</pre></div>
</div>
</div>
<div class="section" id="collecting-responses">
<h2>收集响应（Collecting Responses）<a class="headerlink" href="#collecting-responses" title="永久链接至标题">¶</a></h2>
<p>事件管理器可以收集每一个被通知的侦听者返回的响应，以下这个示例解释了它是如何工作的：</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>

<span class="k">use</span> <span class="nx">Phalcon\Events\Manager</span> <span class="k">as</span> <span class="nx">EventsManager</span><span class="p">;</span>

<span class="nv">$evManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventsManager</span><span class="p">();</span>

<span class="c1">//建立事件管理器以为收集结果响应</span>
<span class="nv">$evManager</span><span class="o">-&gt;</span><span class="na">collectResponses</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>

<span class="c1">//附上一个侦听者</span>
<span class="nv">$evManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;custom:custom&#39;</span><span class="p">,</span> <span class="k">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="s1">&#39;first response&#39;</span><span class="p">;</span>
<span class="p">});</span>

<span class="c1">//附上一个侦听者</span>
<span class="nv">$evManager</span><span class="o">-&gt;</span><span class="na">attach</span><span class="p">(</span><span class="s1">&#39;custom:custom&#39;</span><span class="p">,</span> <span class="k">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="s1">&#39;second response&#39;</span><span class="p">;</span>
<span class="p">});</span>

<span class="c1">//执行fire事件</span>
<span class="nv">$evManager</span><span class="o">-&gt;</span><span class="na">fire</span><span class="p">(</span><span class="s1">&#39;custom:custom&#39;</span><span class="p">,</span> <span class="k">null</span><span class="p">);</span>

<span class="c1">//获取全部收集到的响应</span>
<span class="nb">print_r</span><span class="p">(</span><span class="nv">$evManager</span><span class="o">-&gt;</span><span class="na">getResponses</span><span class="p">());</span>
</pre></div>
</div>
<p>上面示例将输出：</p>
<div class="highlight-html"><div class="highlight"><pre>Array ( [0] =&gt; first response [1] =&gt; second response )
</pre></div>
</div>
</div>
<div class="section" id="implementing-your-own-eventsmanager">
<h2>自定义事件管理器（Implementing your own EventsManager）<a class="headerlink" href="#implementing-your-own-eventsmanager" title="永久链接至标题">¶</a></h2>
<p>如果想要替换Phalcon提供的事件管理器，必须实现 <a class="reference internal" href="../api/Phalcon_Events_ManagerInterface.html"><em>Phalcon\Events\ManagerInterface</em></a> 中的接口。</p>
</div>
</div>


                    </div>
                  </div>
                </div>
            </div>
          </td>
        </tr>
      </table>
    <div class="related">
      <ul>
        <li class="right" >
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="request.html" title="HTTP 请求环境（Request Environment）"
             >下一页</a> |</li>
        <li class="right" >
          <a href="namespaces.html" title="使用命名空间（Working with Namespaces）"
             >上一页</a> |</li> 
      </ul>
    </div>

      <div class="prefooter">
  <div class="container">
      <div class="row">
          <div class="col-sm-3 text-right">
              <span>Follow along:</span>
          </div>
          <div class="col-sm-6 text-center">
              <a href="https://twitter.com/phalconphp" alt="Twitter" class="btn-social btn-social-twitter"><i class="icon-twitter"></i></a>
              <a href="https://www.facebook.com/pages/Phalcon-Framework/134230726685897" alt="Facebook" class="btn-social btn-social-facebook"><i class="icon-facebook"></i></a>
              <a href="https://plus.google.com/102376109340560896457" alt="Google+" class="btn-social btn-social-googleplus"><i class="icon-googleplus"></i></a>
              <a href="https://github.com/phalcon/cphalcon" alt="Github" class="btn-social btn-social-github"><i class="icon-github"></i></a>
          </div>
          <div class="col-sm-3">
          </div>
      </div>
  </div>

</div>
<footer class="footer">
  <div class="container">
      <div class="row">
          <div class="col-xs-4 col-sm-3">
              <h4>Download</h4>
              <ul>
                  <li><a href="http://phalconphp.com/download">Installing Phalcon</a></li>
                  <li><a href="http://docs.phalconphp.com/en/latest/index.html" class="header-nav-link" target="_blank">Documentation</a></li>
                  <li><a href="http://api.phalconphp.com">API</a></li>
                  <li><a href="http://docs.phalconphp.com/en/latest/reference/tutorial.html">Tutorial</a></li>
                  <li><a href="http://docs.phalconphp.com/en/latest/reference/tutorial.html#sample-applications">Sample Applications</a></li>
              </ul>
          </div>
          <div class="col-xs-4 col-sm-3">
              <h4>Community</h4>
              <ul>
                  <li><a href="http://forum.phalconphp.com/" class="header-nav-link" target="_blank">Forum</a></li>
                  <li><a href="https://github.com/phalcon/cphalcon">GitHub</a></li>
                  <li><a href="https://github.com/phalcon/cphalcon/issues">Issue Tracker</a></li>
                  <li><a href="http://stackoverflow.com/questions/tagged/phalcon">Stack Overflow</a></li>
                  <li><a href="http://phalconphp.com/en/testimonials">Testimonials</a></li>
                  <li><a href="http://builtwith.phalconphp.com/">Built with Phalcon</a></li>
                  <li><a href="http://store.phalconphp.com/">Store</a></li>
              </ul>
          </div>
          <div class="col-xs-4 col-sm-2">
              <h4>About</h4>
              <ul>
                  <li><a class="link-black" href="http://blog.phalconphp.com/">Blog</a></li>
                  <li><a href="http://phalconphp.com/en/about">About</a></li>
                  <li><a href="http://phalconphp.com/en/team">Team</a></li>
                  <li><a href="http://phalconphp.com/en/roadmap">Roadmap</a></li>
                  <li><a href="http://phalconphp.com/en/donate">Donate</a></li>
                  <li><a href="http://phalconphp.com/en/consulting">Consulting</a></li>
                  <li><a href="http://phalconphp.com/en/hosting">Hosting</a></li>
              </ul>
          </div>
          <div id="license-spaccer" class="visible-xs"></div>
          <div id="license-wrapper" class="col-xs-12 col-sm-4">
              <p class="license">

                  Found a typo or an error? Want to improve this document? The documentation sources are available on <a href="http://github.com/phalcon/docs">Github</a><br>
                  Need support or have questions? Check our <a href="http://forum.phalconphp.com">Forum</a><br>
                  <br>

                  Phalcon Framework is released under the <a href="https://github.com/phalcon/cphalcon/blob/master/docs/LICENSE.md">new BSD license</a>.<br>
                  Except where otherwise noted, content on this site is licensed under the
                    <a href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License.</a>

                <div class="design">
                  <span>Designed by:</span>

                  <a href="http://www.fog-city.net/" class="fogcity" target="_blank" title="Fog City Software"><span>Fog City Software</span></a>
              </div>
          </div>
      </div>
  </div>
</footer>

    </div>
    <script type="text/javascript">
    $(window).on("load", function(){
      var cx = '009733439235723428699:lh9ltjgvdz8';
      var gcse = document.createElement('script');
      gcse.type = 'text/javascript';
      gcse.async = true;
      gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//www.google.com/cse/cse.js?cx=' + cx;
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(gcse, s);
    });
    </script>

  </body>
</html>